<template>
  <div class="chart-container">
    <ViewChart
      ref="myRef"
      :options="myOption"
    />
  </div>
</template>

<script lang="ts">
import { defineComponent, ref, toRefs, watch, onMounted, defineAsyncComponent, PropType } from 'vue';
import { EChartsOption } from 'echarts'
import { CVariableDataItem, CGraphEntity, CDynamicDataItem, CDataNode } from 'stores/editorModels';
import { CChartPropertyItem } from 'components/views/chart/chartViewModel';
import { useMessageNotify } from 'src/hook/common/useMessageNotify';
const ViewChart = defineAsyncComponent(() => import('./ViewChart.vue'));

export default defineComponent({
  name: 'ViewChartSimpleGauge',
  components: {
    ViewChart
  },
  props: {
    detail: {
      type: Object,
      default: () => {
        return {} as CGraphEntity
      }
    },
    dynamicData: {
      type: Array as PropType<CVariableDataItem[]>,
      default: () => {
        return [] as CVariableDataItem[]
      }
    }
  },
  setup (props, context) {
    // 响应数据解构
    const {
      detail,
      dynamicData
    } = toRefs(props);

    //错误通知
    const {
      showMessage
    } = useMessageNotify();

    // chart dom,InstanceType获取子组件的类型
    let myRef = ref<InstanceType<typeof ViewChart> | null>(null);
    let param = ref<CChartPropertyItem>({
      title: '',
      color: '',
      unit: '',
      min: 0,
      max: 200,
      xDataNum: 0
    });

    //初始数据
    let xyData = ref<CDynamicDataItem[]>([
      {
        vid: 0,
        name: '油耗',
        value: 50
      }
    ]);

    //chart数据样式
    let myOption: EChartsOption = {
      tooltip: {
        formatter: '{a} <br/>{b} : {c}%'
      },
      series: []
    };

    //动态增加曲线
    const addToChart = (): void => {
      if (myOption.series) {
        //series清空
        (myOption.series as any).length = 0;

        let serial_item = {
          name: param.value.title, //名称
          type: 'gauge', //类型
          radius: '90%',  // 仪表盘半径，可以是相对于容器高宽中较小的一项的一半的百分比，也可以是绝对的数值
          center: ['50%', '50%'], // 中心（圆心）坐标，数组的第一项是横坐标，第二项是纵坐标。百分比或者绝对值
          startAngle: 225,  // 起始角度
          endAngle: -45,    // 结束角度
          min: param.value.min,
          max: param.value.max,
          splitNumber: 10,
          axisLine: {     // 坐标轴线
            lineStyle: { // 属性lineStyle控制线条样式
              width: 10,
              color: [
                [0.25, '#FF6E76'],
                [0.5, '#FDDD60'],
                [0.75, '#58D9F9'],
                [1, '#7CFFB2']
              ]
            }
          },
          splitLine: {  // 分割线样式
            length: 15, // 属性length控制线长
            lineStyle: { // 属性lineStyle（详见lineStyle）控制线条样式
              width: 5,
              color: 'auto'
            }
          },
          axisTick: {  // 刻度样式
            length: 6, // 属性length控制线长
            lineStyle: { // 属性lineStyle控制线条样式
              color: 'inherited'
            }
          },
          axisLabel: {  // 刻度标签
            textStyle: { // 属性lineStyle控制线条样式
              fontWeight: 'bolder',
              color: 'inherited'
            }
          },
          pointer: {    // 仪表盘指针
            show: true,
            itemStyle: {
              color: 'inherit'
            }
          },
          detail: {  // 仪表盘详情，用于显示数据
            show: true,
            valueAnimation: true,
            formatter: '{value}' + param.value.unit,
            color: param.value.color,
            padding: 0
          },
          data: xyData.value
        };

        (myOption.series as any).push(serial_item);
      }
    };

    //属性更新
    const configProperty = () => {
      //个性化属性,计算长度，进行校验，一旦格式出错，涉及到数据错位，报错
      if ((detail.value) && (detail.value?.propsItem) &&
        (detail.value?.propsItem.length > 0)) {
        //取出属性值
        let i = 0;
        let num1, num2, num3;
        param.value.title = (detail.value.propsItem[i++].value);
        param.value.color = (detail.value.propsItem[i++].value);
        param.value.unit = (detail.value.propsItem[i++].value);
        num1 = parseInt((detail.value.propsItem[i++].value));
        num2 = parseInt((detail.value.propsItem[i++].value));
        num3 = parseInt((detail.value.propsItem[i++].value));
        if (!isNaN(num1) && !isNaN(num2) && !isNaN(num3)) {
          param.value.min = num1;
          param.value.max = num2;
          param.value.xDataNum = num3;
        } else {
          showMessage('ChartSimpleGauge属性类型不正确！');
        }
      } else {
        showMessage('ChartSimpleGauge属性个数不正确！');
      }

      //生成数据节点
      if ((detail.value.dataItem) &&
        (detail.value?.dataItem.length > 0)) {
        xyData.value.length = 0;
        detail.value.dataItem.forEach((item: CDataNode) => {
          xyData.value.push({
            vid: item.variableValue,
            name: item.nodeValue,
            value: 0
          });
        });
      }
    }

    //更新数据
    const refreshDynamicData = () => {
      //动态数据
      if ((dynamicData.value) && (dynamicData.value.length > 0)) {
        dynamicData.value.forEach((el, index) => {
          if (xyData.value[index].vid === el.varId) {
            xyData.value[index].value = el.vData;
          }
        });
      }
    }

    //初始化
    const init = () => {
      configProperty();
      refreshDynamicData();
      addToChart();

      if (myRef.value) {
        myRef.value.updateView();
        myRef.value.onResize();
      }
    }

    // watch dom尺寸变化,调整子控件大小
    watch(() => detail, () => {
      init();
    }, { deep: true });

    //监视变量变化
    watch(() => dynamicData, () => {
      refreshDynamicData();
    }, { deep: true })

    //挂载组件
    onMounted(() => {
      init();
    });

    return {
      myRef,
      detail,
      myOption
    };
  }
});
</script>

<style lang="scss" scoped>
.chart-container {
  position: absolute;
  left: 0px;
  top: 0px;
  width: 100%;
  height: 100%;
  text-align: center;
}
</style>
